import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 专业组分组测试类
 * 用于验证getMajorGroupKey方法的智能匹配逻辑
 */
public class 专业组分组测试 {
    
    public static void main(String[] args) {
        专业组分组测试 test = new 专业组分组测试();
        test.testMajorGrouping();
    }
    
    public void testMajorGrouping() {
        System.out.println("=== 专业组分组测试 ===");
        
        // 模拟专业录取信息数据
        List<MockMajorAdmissionInfo> majors = Arrays.asList(
            // 同一学校的不同专业组格式
            new MockMajorAdmissionInfo("school001", "计算机科学与技术", "1093（W003）", "（W003）"),
            new MockMajorAdmissionInfo("school001", "软件工程", "1093（W003）", "（003）"),  // 数字部分相同
            new MockMajorAdmissionInfo("school001", "网络工程", "1094（W001）", "（W001）"),
            new MockMajorAdmissionInfo("school001", "信息安全", "1094（W001）", "（001）"),  // 数字部分相同
            
            // 另一个学校的专业组
            new MockMajorAdmissionInfo("school002", "电子信息工程", "1095（L005）", "（L005）"),
            new MockMajorAdmissionInfo("school002", "通信工程", "1095（L005）", "（005）"),  // 数字部分相同
            new MockMajorAdmissionInfo("school002", "自动化", "1096（L002）", "（L002）"),
            
            // 测试边界情况
            new MockMajorAdmissionInfo("school003", "机械工程", "1097（M001）", null),  // 无招生计划专业组
            new MockMajorAdmissionInfo("school003", "材料科学", null, "（M001）"),  // 无subjectGroup
            new MockMajorAdmissionInfo("school003", "化学工程", "1098（M002）", "（M999）")  // 不匹配的专业组
        );
        
        // 测试分组逻辑
        Map<String, List<MockMajorAdmissionInfo>> groupedMajors = majors.stream()
            .collect(Collectors.groupingBy(this::getMajorGroupKey));
        
        System.out.println("分组结果:");
        for (Map.Entry<String, List<MockMajorAdmissionInfo>> entry : groupedMajors.entrySet()) {
            String groupKey = entry.getKey();
            List<MockMajorAdmissionInfo> groupMajors = entry.getValue();
            
            System.out.println("\n专业组: " + groupKey + " (" + groupMajors.size() + "个专业)");
            for (MockMajorAdmissionInfo major : groupMajors) {
                System.out.println("  - " + major.majorName + 
                    " | subjectGroup: " + major.subjectGroup + 
                    " | specialGroupName: " + major.specialGroupName);
            }
        }
        
        // 验证期望的分组结果
        System.out.println("\n=== 分组验证 ===");
        
        // 验证1：003组应该包含计算机科学与技术和软件工程（数字部分统一）
        String group003 = "school001_003";
        if (groupedMajors.containsKey(group003)) {
            List<MockMajorAdmissionInfo> group003Majors = groupedMajors.get(group003);
            boolean hasComputer = group003Majors.stream().anyMatch(m -> "计算机科学与技术".equals(m.majorName));
            boolean hasSoftware = group003Majors.stream().anyMatch(m -> "软件工程".equals(m.majorName));
            System.out.println("✓ 003组验证: 包含计算机科学与技术=" + hasComputer + ", 包含软件工程=" + hasSoftware);
        } else {
            System.out.println("✗ 003组验证失败: 未找到分组 " + group003);
        }
        
        // 验证2：001组应该包含网络工程和信息安全（数字部分统一）
        String group001 = "school001_001";
        if (groupedMajors.containsKey(group001)) {
            List<MockMajorAdmissionInfo> group001Majors = groupedMajors.get(group001);
            boolean hasNetwork = group001Majors.stream().anyMatch(m -> "网络工程".equals(m.majorName));
            boolean hasSecurity = group001Majors.stream().anyMatch(m -> "信息安全".equals(m.majorName));
            System.out.println("✓ 001组验证: 包含网络工程=" + hasNetwork + ", 包含信息安全=" + hasSecurity);
        } else {
            System.out.println("✗ 001组验证失败: 未找到分组 " + group001);
        }
        
        // 验证3：005组应该包含电子信息工程和通信工程（数字部分统一）
        String group005 = "school002_005";
        if (groupedMajors.containsKey(group005)) {
            List<MockMajorAdmissionInfo> group005Majors = groupedMajors.get(group005);
            boolean hasElectronic = group005Majors.stream().anyMatch(m -> "电子信息工程".equals(m.majorName));
            boolean hasCommunication = group005Majors.stream().anyMatch(m -> "通信工程".equals(m.majorName));
            System.out.println("✓ 005组验证: 包含电子信息工程=" + hasElectronic + ", 包含通信工程=" + hasCommunication);
        } else {
            System.out.println("✗ 005组验证失败: 未找到分组 " + group005);
        }
        
        System.out.println("\n总分组数: " + groupedMajors.size());
        System.out.println("分组键列表: " + groupedMajors.keySet());
    }
    
    /**
     * 模拟getMajorGroupKey方法（使用数字部分统一分组）
     */
    private String getMajorGroupKey(MockMajorAdmissionInfo info) {
        String schoolKey = info.schoolUuid;
        String majorGroupKey = "";
        
        // 优先使用招生计划中的专业组信息
        if (info.specialGroupName != null && !info.specialGroupName.trim().isEmpty()) {
            String extractedCode = extractSpecialGroupCode(info.specialGroupName.trim());
            if (extractedCode != null) {
                // 进一步提取数字部分作为统一的分组键
                String numberPart = extractNumberPart(extractedCode);
                majorGroupKey = numberPart != null ? numberPart : extractedCode;
            } else {
                majorGroupKey = info.specialGroupName.trim();
            }
            System.out.println("专业 " + info.majorName + " 使用招生计划专业组: " + info.specialGroupName + " -> 提取编号: " + extractedCode + " -> 数字部分: " + majorGroupKey);
            return schoolKey + "_" + majorGroupKey;
        }
        
        // 备选方案：使用subjectGroup字段
        if (info.subjectGroup != null && !info.subjectGroup.trim().isEmpty()) {
            String extractedCode = extractSpecialGroupCode(info.subjectGroup.trim());
            if (extractedCode != null) {
                // 进一步提取数字部分作为统一的分组键
                String numberPart = extractNumberPart(extractedCode);
                majorGroupKey = numberPart != null ? numberPart : extractedCode;
            } else {
                majorGroupKey = info.subjectGroup.trim();
            }
            System.out.println("专业 " + info.majorName + " 使用subjectGroup专业组: " + info.subjectGroup + " -> 提取编号: " + extractedCode + " -> 数字部分: " + majorGroupKey);
        } else {
            // 使用专业名称核心部分作为备选
            majorGroupKey = extractCoreMajorName(info.majorName);
            System.out.println("专业 " + info.majorName + " 使用专业名称核心: " + majorGroupKey);
        }
        
        String finalKey = schoolKey + "_" + majorGroupKey;
        return finalKey;
    }
    
    /**
     * 从专业组字符串中提取专业组编号
     */
    private String extractSpecialGroupCode(String specialGroup) {
        if (specialGroup == null || specialGroup.trim().isEmpty()) {
            return null;
        }
        
        String trimmed = specialGroup.trim();
        
        // 1. 提取中文括号内的内容：（003）或（W003）
        Pattern chineseParenPattern = Pattern.compile("（([^）]+)）");
        Matcher chineseMatcher = chineseParenPattern.matcher(trimmed);
        if (chineseMatcher.find()) {
            String content = chineseMatcher.group(1);
            if (content.matches("[A-Za-z]\\d+")) {
                return content;
            }
            if (content.matches("\\d+")) {
                return content;
            }
            return content;
        }
        
        // 2. 提取英文括号内的内容：(003)或(W003)
        Pattern englishParenPattern = Pattern.compile("\\(([^)]+)\\)");
        Matcher englishMatcher = englishParenPattern.matcher(trimmed);
        if (englishMatcher.find()) {
            String content = englishMatcher.group(1);
            if (content.matches("[A-Za-z]\\d+")) {
                return content;
            }
            if (content.matches("\\d+")) {
                return content;
            }
            return content;
        }
        
        // 3. 如果是字母+数字格式（如W003），直接返回
        if (trimmed.matches("[A-Za-z]\\d+")) {
            return trimmed;
        }
        
        // 4. 如果是纯数字格式（如003），直接返回
        if (trimmed.matches("\\d+")) {
            return trimmed;
        }
        
        // 5. 如果包含数字，尝试提取最后的数字部分
        Pattern numberPattern = Pattern.compile("([A-Za-z]?\\d+)$");
        Matcher numberMatcher = numberPattern.matcher(trimmed);
        if (numberMatcher.find()) {
            return numberMatcher.group(1);
        }
        
        return null;
    }
    
    /**
     * 从专业组编号中提取数字部分
     */
    private String extractNumberPart(String code) {
        if (code == null || code.trim().isEmpty()) {
            return null;
        }
        
        String trimmed = code.trim();
        
        // 如果是纯数字，直接返回
        if (trimmed.matches("\\d+")) {
            return trimmed;
        }
        
        // 如果是字母+数字格式，提取数字部分
        Pattern pattern = Pattern.compile("[A-Za-z]*(\\d+)");
        Matcher matcher = pattern.matcher(trimmed);
        if (matcher.find()) {
            return matcher.group(1);
        }
        
        return null;
    }
    
    /**
     * 提取专业名称核心部分
     */
    private String extractCoreMajorName(String majorName) {
        if (majorName == null || majorName.trim().isEmpty()) {
            return "unknown";
        }
        
        // 去除括号内容
        String core = majorName.replaceAll("[（(][^）)]*[）)]", "").trim();
        
        // 如果包含"工程"、"科学"等关键词，提取前面的部分
        if (core.contains("工程")) {
            int index = core.indexOf("工程");
            return core.substring(0, index + 2);
        }
        if (core.contains("科学")) {
            int index = core.indexOf("科学");
            return core.substring(0, index + 2);
        }
        
        // 取前4个字符作为核心
        return core.length() > 4 ? core.substring(0, 4) : core;
    }
    
    /**
     * 模拟专业录取信息类
     */
    static class MockMajorAdmissionInfo {
        String schoolUuid;
        String majorName;
        String subjectGroup;
        String specialGroupName;
        
        public MockMajorAdmissionInfo(String schoolUuid, String majorName, String subjectGroup, String specialGroupName) {
            this.schoolUuid = schoolUuid;
            this.majorName = majorName;
            this.subjectGroup = subjectGroup;
            this.specialGroupName = specialGroupName;
        }
    }
}